package com.weasel.weixin.commons.user;

import com.google.common.collect.ImmutableMap;
import com.weasel.helper.JsonHelper;
import com.weasel.http.HttpClientSecretary;
import com.weasel.http.helper.HttpResponseHelper;
import com.weasel.weixin.commons.CommonRequest;
import com.weasel.weixin.commons.config.CommonConfig;
import com.weasel.weixin.commons.config.CommonConsts;
import com.weasel.weixin.commons.user.bean.UserInfo;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * Created by Dylan on 2015/10/13.
 */
public class UserInfoRequest extends CommonRequest {


    public UserInfoRequest(CommonConfig config) {
        super(config);
    }

    /**
     * 网页授权方式获取用户信息
     * @param accessToken  网页授权接口调用凭证，跟AccessTokenRequest接口获取的accessToken不同
     * @param openId  用户的唯一标识
     * @param lang  返回国家地区语言版本，zh_CN 简体，zh_TW 繁体，en 英语
     * @return
     * @throws IOException
     */
    public static UserInfoResponse getOauth2UserInfo(String accessToken, String openId, String lang) throws IOException {

        return getUserInfo(CommonConsts.OAUTH2_USER_INFO_URL, ImmutableMap.of("access_token", accessToken, "openid", openId, "lang", lang));
    }

    /**网页授权方式获取用户信息
     * @param accessToken 网页授权接口调用凭证,跟AccessTokenRequest接口获取的accessToken不同
     * @param openId 用户的唯一标识
     * @return
     * @throws IOException
     */
    public static UserInfoResponse getOauth2UserInfo(String accessToken, String openId) throws IOException {

        return getOauth2UserInfo(accessToken, openId, "zh_CN");
    }

    /**
     *获取用户信息
     * @param openId 普通用户的标识，对当前公众号唯一
     * @return
     * @throws ExecutionException
     * @throws IOException
     */
    public UserInfoResponse getUserInfo(String openId) throws ExecutionException, IOException {

        return getUserInfo(CommonConsts.USER_INFO_URL, ImmutableMap.of("access_token", getAccessToken(), "openid", openId, "lang", "zh_CN"));
    }

    /**
     *获取用户信息
     * @param openId 普通用户的标识，对当前公众号唯一
     * @param lang 返回国家地区语言版本，zh_CN 简体，zh_TW 繁体，en 英语
     * @return
     * @throws ExecutionException
     * @throws IOException
     */
    public UserInfoResponse getUserInfo(String openId,String lang) throws ExecutionException, IOException {

        return getUserInfo(CommonConsts.USER_INFO_URL, ImmutableMap.of("access_token", getAccessToken(), "openid", openId, "lang", lang));
    }

    /**
     * 批量获取用户信息
     * @param openIds 普通用户的标识，对当前公众号唯一
     * @return
     * @throws ExecutionException
     * @throws IOException
     */
    public UserInfoListResponse getUserInfoList(String [] openIds) throws ExecutionException, IOException {

        return getUserInfoList(openIds, "zh-CN");
    }

    public UserInfoListResponse getUserInfoList(String [] openIds,String lang) throws ExecutionException, IOException {

        List<Map<String,String>> _openIds = new LinkedList<>();
        for(String openId : openIds){
            Map<String,String> map = new HashMap<>();
            map.put("openid",openId);
            map.put("lang",lang);
            _openIds.add(map);
        }

        UserInfoListResponse response = HttpClientSecretary.post()
                                                           .withURI(getBaseUrl(CommonConsts.USER_INFO_LIST_URL))
                                                           .withParams(ImmutableMap.of("user_list",_openIds))
                                                           .doItWithJson(UserInfoListResponse.class);
        return response;
    }

    /**
     * 更新用户备注
     * @param openId 普通用户的标识，对当前公众号唯一
     * @param remark 新的备注名，长度必须小于30字符
     * @return
     * @throws ExecutionException
     * @throws IOException
     */
    public UserInfoResponse updateRemark(String openId,String remark) throws ExecutionException, IOException {

        UserInfoResponse response = HttpClientSecretary.post()
                                                       .withURI(getBaseUrl(CommonConsts.UPDATE_USER_INFO_REMARK_URL))
                                                       .withParam(ImmutableMap.of("openid",openId,"remark",remark))
                                                       .doItWithJson(UserInfoResponse.class);
        return response;
    }

    private static UserInfoResponse getUserInfo(String url,Map<String,String> params) throws IOException {

        UserInfoResponse response = HttpClientSecretary.get()
                                                       .withURI(url)
                                                       .withParams(params)
                                                       .doIt(new ResponseHandler<UserInfoResponse>() {
                                                           @Override
                                                           public UserInfoResponse handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                                                               String jsonResponse = HttpResponseHelper.getResponseString(response);
                                                               UserInfoResponse userInfoResponse = JsonHelper.fromJsonString(jsonResponse, UserInfoResponse.class);
                                                               if (userInfoResponse.isOK()) {
                                                                   UserInfo userInfo = JsonHelper.fromJsonString(jsonResponse, UserInfo.class);
                                                                   userInfoResponse.setUser(userInfo);
                                                               }
                                                               return userInfoResponse;
                                                           }
                                                       });
        return response;
    }
}
